package com.sls.web.manager.recharge.service.impl;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sls.core.common.CommonUtil;
import com.sls.core.socket.Head;
import com.sls.core.socket.SocketDTO;
import com.sls.core.socket.TransmissionCode;
import com.sls.web.manager.common.Constants;
import com.sls.web.manager.execption.ManagerException;
import com.sls.web.manager.page.Pagination;
import com.sls.web.manager.pojo.UserInfoVO;
import com.sls.web.manager.querybean.base.BaseQuery;
import com.sls.web.manager.recharge.pojo.Area;
import com.sls.web.manager.recharge.querybean.AreaQuery;
import com.sls.web.manager.recharge.service.AreaService;
import com.sls.web.manager.socket.SuperService;
import com.whalin.MemCached.MemCachedClient;

/**
 * @author sxf
 * 
 */
@Service("areaService")
public class AreaServiceImpl extends SuperService implements AreaService {
	private static Logger log = Logger.getLogger(AreaServiceImpl.class);
	@Resource(name = "memcachedClient")
	private MemCachedClient memcachedClient;

	/**
	 * @param serviceCode
	 * @param sendObj
	 * @param userInfoVO
	 * @param classType
	 *            类型信息(如:String,为String.class)
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public <T> T callService(String serviceCode, Head head, Object sendObj,
			UserInfoVO userInfoVO, Object... classType) throws Exception {
		Gson gson = CommonUtil.gson();
		if (head == null) {
			head = new Head();
			head.setRequestId(UUID.randomUUID().toString());
			head.setServiceCode(serviceCode);
			head.setIp(userInfoVO.getCurrentIp());
			head.setUserId(userInfoVO.getUserId());
		}
		SocketDTO requestDTO = super.send(head, sendObj);
		if (!TransmissionCode.SUCCESS.getCode().equals(
				requestDTO.getHead().getResponseCode())) {
			throw new ManagerException(requestDTO.getHead()
					.getResponseMessage());
		}
		String body = requestDTO.getBody();
		T t = null;
		if (body != null) {
			if (classType != null && classType.length > 0) {
				if (classType[0] instanceof Class) {
					t = gson.fromJson(body, (Class<T>) classType[0]);
				} else if (classType[0] instanceof Type) {
					t = gson.fromJson(body, (Type) classType[0]);
				}
			}
		}
		return t;
	}

	public boolean insert(Area info, UserInfoVO userInfoVO) throws Exception {
		this.callService(Constants.INSERT_AREA, null, info, userInfoVO);
		return true;
	}

	public List<Area> queryList(AreaQuery query, UserInfoVO userInfoVO)
			throws Exception {
		log.info("Enter AreaService queryPage method...");
		List<Area> infoPage = callService(Constants.QUERY_AREA_LIST, null,
				query, userInfoVO, new TypeToken<List<Area>>() {
				}.getType());
		log.info("Leave AreaService queryPage method...");
		return infoPage;
	}

	@SuppressWarnings("unchecked")
	public List<Area> queryAllList(Integer grade, UserInfoVO userInfoVO)
			throws Exception {
		List<Area> areaList = new LinkedList<Area>();
		if (grade != null && grade >= 1 && grade <= 3) {
			Object obj = memcachedClient.get("AREAINFORMATION_" + grade);
			if (obj == null) {
				List<Area> listTemp = queryListByGrade(grade, userInfoVO);
				memcachedClient.set("AREAINFORMATION_" + grade, listTemp);
				obj = listTemp;
			}
			areaList = (List<Area>) obj;
		} else if (grade == null) {
			for (int i = 1; i <= 3; i++) {
				Object obj = memcachedClient.get("AREAINFORMATION_" + i);
				if (obj == null) {
					List<Area> listTemp = queryListByGrade(i, userInfoVO);
					memcachedClient.set("AREAINFORMATION_" + i, listTemp);
					obj = listTemp;
				}
				areaList.addAll((List<Area>) obj);
			}
		}
		return areaList;
	}

	private List<Area> queryListByGrade(int grade, UserInfoVO userInfoVO)
			throws Exception {
		AreaQuery query = new AreaQuery();
		query.setPageSize(25);
		if (grade >= 1 && grade <= 3) {
			query.setGrade(grade);
		}

		List<Area> areaList = new LinkedList<Area>();
		Pagination<Area> page = queryPage(query, userInfoVO);
		if (page.getList() != null) {
			areaList.addAll(page.getList());
		}
		int count = page.getRowCount();
		if (query.getPageSize() == 0) {
			query.setPageSize(1);
		}
		for (int i = 1; i < Math.ceil(count * 1.0 / query.getPageSize()); i++) {
			query.setCurrentPage(i + 1);
			page = queryPage(query, userInfoVO);
			if (page.getList() != null) {
				areaList.addAll(page.getList());
			}
		}
		return areaList;
	}

	/**
	 * 查询全部信息(List)
	 * 
	 * @param query
	 * @param serviceCode
	 * @param userInfoVO
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private <T> List<T> queryAllList(BaseQuery query, String serviceCode,
			UserInfoVO userInfoVO, Object... classType) throws Exception {
		query.setCurrentPage(1);
		query.setOffset(10);
		List<T> resultList = new LinkedList<T>();
		Pagination<T> page = callService(serviceCode, null, query, userInfoVO,
				classType);
		if (page.getList() != null) {
			resultList.addAll(page.getList());
		}
		int count = page.getRowCount();
		if (query.getPageSize() == 0) {
			query.setPageSize(1);
		}
		for (int i = 0; i < Math.ceil(count * 1.0 / query.getPageSize()); i++) {
			query.setCurrentPage(i + 1);
			page = callService(serviceCode, null, query, userInfoVO, classType);
			if (page.getList() != null) {
				resultList.addAll(page.getList());
			}
		}
		return resultList;
	}

	public Pagination<Area> queryPage(AreaQuery query, UserInfoVO userInfoVO)
			throws Exception {
		log.info("Enter AreaService queryPage method...");
		Pagination<Area> infoPage = callService(Constants.QUERY_AREA_PAGE,
				null, query, userInfoVO, new TypeToken<Pagination<Area>>() {
				}.getType());
		log.info("Leave AreaService queryPage method...");
		return infoPage;
	}

	public Area queryOne(AreaQuery query, UserInfoVO userInfoVO)
			throws Exception {
		log.info("Enter AreaService queryPage method...");
		Area infoPage = callService(Constants.QUERY_AREA_ONE, null, query,
				userInfoVO, Area.class);
		log.info("Leave AreaService queryPage method...");
		return infoPage;
	}

	public boolean update(Area info, UserInfoVO userInfoVO) throws Exception {
		this.callService(Constants.UPDATE_AREA, null, info, userInfoVO);
		return true;
	}

	public boolean delete(Area info, UserInfoVO userInfoVO) throws Exception {
		this.callService(Constants.DELETE_AREA, null, info, userInfoVO);
		return true;
	}

	public Area queryOneInMemcache(AreaQuery query, UserInfoVO userInfoVO)
			throws Exception {
		List<Area> areaAllList = queryAllList(null, userInfoVO);
		Area resultArea = null;
		for (Iterator<Area> it = areaAllList.iterator(); it.hasNext();) {
			Area area = (Area) it.next();
			if (area.getCode().equals(query.getCode())) {
				resultArea = area;
			}
		}
		return resultArea;
	}

	public List<Area> queryListInMemcache(AreaQuery query, UserInfoVO userInfoVO)
			throws Exception {
		List<Area> areaAllList = queryAllList(null, userInfoVO);
		List<Area> areaList = new ArrayList<Area>();
		for (Iterator<Area> it = areaAllList.iterator(); it.hasNext();) {
			Area area = (Area) it.next();
			boolean flag = false;
			if (StringUtils.isNotBlank(query.getCode())) {
				if (area.getCode().equals(query.getCode())) {
					flag = true;
				} else {
					flag = false;
				}
			}
			if (StringUtils.isNotBlank(query.getParentCode())) {
				if (area.getParentCode().equals(query.getParentCode())) {
					flag = true;
				} else {
					flag = false;
				}
			}
			if (flag) {
				areaList.add(area);
			}

		}
		return areaList;
	}
}
